#ifndef ILRT_RUNTIME_H_
#define ILRT_RUNTIME_H_

#include <illib/Log.h>
#include <ilrt/Type.h>
#include <ilrt/Numeric.h>
#include <ilrt/String.h>
#include <ilrt/Collection.h>
#include <ilrt/Interpreter.h>

namespace ilrt{
	class Types : private illib::BasicLinkedList::List{
	protected:
		;
		friend class BasicType;
	public:
		NoneType None;
		UndefinedType Undefined;
		StringType String;
		BooleanType Boolean;
		IndexType Index;
		UnsignedInt8Type UnsignedInt8;
		UnsignedInt16Type UnsignedInt16;
		UnsignedInt32Type UnsignedInt32;
		UnsignedInt64Type UnsignedInt64;
		SignedInt8Type SignedInt8;
		SignedInt16Type SignedInt16;
		SignedInt32Type SignedInt32;
		SignedInt64Type SignedInt64;
		Float32Type Float32;
		Float64Type Float64;
		InterpreterStackType InterpreterStack;
		Types(Runtime & runtime) :
			None(runtime),
			Undefined(runtime),
			String(runtime),
			Boolean(runtime),
			Index(runtime),
			UnsignedInt8(runtime),
			UnsignedInt16(runtime),
			UnsignedInt32(runtime),
			UnsignedInt64(runtime),
			SignedInt8(runtime),
			SignedInt16(runtime),
			SignedInt32(runtime),
			SignedInt64(runtime),
			Float32(runtime),
			Float64(runtime),
			InterpreterStack(runtime)
		{
		}
		void addType(BasicType & type){
			add(type, length());
		}
	};
	class Runtime {
	protected:
		static Runtime * instance_;
		friend Runtime & runtime();
		friend void runtime(Runtime & runtime);
	public:
		Types types;
		Runtime() :
			types(*this)
		{
			instance_ = this;
		}
		~Runtime(){
		}
	};
	extern Runtime & runtime();
	extern void runtime(Runtime & runtime);
};

#endif
